package myJs.myPkg.plotly

import java.lang.{Boolean => JBoolean, Double => JDouble, Integer => JInt}

import scala.scalajs.js
import scala.scalajs.js.Dynamic.{global => g}
import scala.scalajs.js.{Promise, |}
import slinky.readwrite.ObjectOrWritten

import scala.concurrent.Future
import scala.scalajs.js
import scala.scalajs.js.Dynamic.{global => g}
import scala.scalajs.js.annotation.JSImport

sealed trait PlotData

@js.native
trait HoverInfo extends js.Object

object HoverInfo {

  val text = "text".asInstanceOf[HoverInfo]

  val y = "y".asInstanceOf[HoverInfo]

  val all = "all".asInstanceOf[HoverInfo]

}

case class Bar(
                x: List[String],
                y: List[Double],
                `type`: String = "bar",
                hoverinfo: js.UndefOr[HoverInfo] = js.undefined,
                text: js.UndefOr[List[String]] = js.undefined,
                hovertext: js.UndefOr[List[String]] = js.undefined,
              ) extends PlotData

case class Box(
                y: List[Int | Double],
                name: String,
                `type`: String = "box",
                hovertext: js.UndefOr[String] = js.undefined,
                hoverinfo: js.UndefOr[HoverInfo] = js.undefined,
              ) extends PlotData

case class Marker(
                   color: List[String],
                   size: js.UndefOr[Int] = js.undefined
                 )

case class Scatter(
                    x: List[String],
                    y: List[String],
                    name: js.UndefOr[String] = js.undefined,
                    `type`: String = "box",
                    hovertext: js.UndefOr[String] = js.undefined,
                    hoverinfo: js.UndefOr[HoverInfo] = js.undefined,
                    marker: js.UndefOr[Marker] = js.undefined,
                  ) extends PlotData

case class Font(
                 size: js.UndefOr[Int] = js.undefined
               )

case class Axis(
                 tickangle: js.UndefOr[Double] = js.undefined,
                 title: js.UndefOr[String] = js.undefined,
                 tickformat: js.UndefOr[String] = js.undefined,
                 dtick: js.UndefOr[String] = js.undefined,
                 fixedrange: js.UndefOr[Boolean] = js.undefined,
                 tickfont: js.UndefOr[Font] = js.undefined,
                 gridwidth: js.UndefOr[Int] = js.undefined,
                 titlefont: js.UndefOr[Font] = js.undefined,
               )

case class Margin(
                   l: js.UndefOr[Int] = js.undefined,
                   r: js.UndefOr[Int] = js.undefined,
                   t: js.UndefOr[Int] = js.undefined, b: Int)

@js.native
trait HoverMode extends js.Object

object HoverMode {

  val closest = "closest".asInstanceOf[HoverMode]

}

case class Layout(
                   xaxis: js.UndefOr[Axis] = js.undefined,
                   margin: js.UndefOr[Margin] = js.undefined,
                   yaxis: js.UndefOr[Axis] = js.undefined,
                   hovermode: js.UndefOr[HoverMode] = js.undefined,
                   showlegend: js.UndefOr[Boolean] = js.undefined,
                   title: js.UndefOr[String] = js.undefined,
                   width: js.UndefOr[Int] = js.undefined,
                   height: js.UndefOr[Int] = js.undefined,
                   font: js.UndefOr[Font] = js.undefined,
                 )

case class Config(displayModeBar: Boolean = true)

case class ImageOptions(
                         data: ObjectOrWritten[List[PlotData]],
                         layout: js.UndefOr[ObjectOrWritten[Layout]]
                       )

case class ImageLayout(
                        width: Int = 800,
                        height: Int = 600
                      )

@js.native
@JSImport("plotly.js-dist-min", JSImport.Default)
object Plotly extends js.Object {

  def newPlot(div: String, data: ObjectOrWritten[List[PlotData]],
              layout: js.UndefOr[ObjectOrWritten[Layout]] = js.undefined,
              config: js.UndefOr[ObjectOrWritten[Config]] = js.undefined
             ): js.Any = js.native

  def toImage(options: ObjectOrWritten[ImageOptions],
              layout: js.UndefOr[ObjectOrWritten[ImageLayout]] = js.undefined,
             ): js.Promise[String] = js.native

}
